import { Op } from 'sequelize';
import bcrypt from 'bcrypt';
import { User, UserAttributes } from '../models/User';
import { UserAddress, UserAddressAttributes } from '../models/UserAddress';
import { 
  CreateUserRequest, 
  UpdateUserRequest, 
  UserQueryParams, 
  UserResponse, 
  UserListResponse,
  UserStatsResponse,
  CreateUserAddressRequest,
  UpdateUserAddressRequest,
  UserAddressResponse,
  AddressQueryParams,
  AddressListResponse
} from '../types/user';
import { AppError } from '../utils/errors';
import logger from '../utils/logger';

export class UserService {
  /**
   * 创建用户
   */
  async createUser(userData: CreateUserRequest): Promise<UserResponse> {
    try {
      // 检查用户名和邮箱是否已存在
      const existingUser = await User.findOne({
        where: {
          [Op.or]: [
            { username: userData.username },
            { email: userData.email },
            ...(userData.phone ? [{ phone: userData.phone }] : [])
          ]
        }
      });

      if (existingUser) {
        if (existingUser.username === userData.username) {
          throw new AppError('用户名已存在', 400);
        }
        if (existingUser.email === userData.email) {
          throw new AppError('邮箱已存在', 400);
        }
        if (existingUser.phone === userData.phone) {
          throw new AppError('手机号已存在', 400);
        }
      }

      // 加密密码
      const hashedPassword = await bcrypt.hash(userData.password, 10);

      // 创建用户
      const createData: any = {
        ...userData,
        password: hashedPassword,
      };
      
      // 处理生日字段类型转换
      if (createData.birthday) {
        createData.birthday = new Date(createData.birthday);
      }
      
      const user = await User.create(createData);

      logger.info(`用户创建成功: ${user.username} (ID: ${user.id})`);
      return this.formatUserResponse(user);
    } catch (error) {
      logger.error('创建用户失败:', error);
      throw error;
    }
  }

  /**
   * 获取用户列表
   */
  async getUserList(params: UserQueryParams): Promise<UserListResponse> {
    try {
      const {
        page = 1,
        limit = 10,
        keyword,
        status,
        gender,
        levelId,
        startDate,
        endDate,
        sortBy = 'id',
        sortOrder = 'DESC'
      } = params;

      const offset = (page - 1) * limit;
      const where: any = {};

      // 关键词搜索
      if (keyword) {
        where[Op.or] = [
          { username: { [Op.like]: `%${keyword}%` } },
          { email: { [Op.like]: `%${keyword}%` } },
          { nickname: { [Op.like]: `%${keyword}%` } },
          { phone: { [Op.like]: `%${keyword}%` } }
        ];
      }

      // 状态筛选
      if (status !== undefined) {
        where.status = status;
      }

      // 性别筛选
      if (gender !== undefined) {
        where.gender = gender;
      }

      // 会员等级筛选
      if (levelId !== undefined) {
        where.levelId = levelId;
      }

      // 日期范围筛选
      if (startDate || endDate) {
        where.createdAt = {};
        if (startDate) {
          where.createdAt[Op.gte] = new Date(startDate);
        }
        if (endDate) {
          where.createdAt[Op.lte] = new Date(endDate);
        }
      }

      const { count, rows } = await User.findAndCountAll({
        where,
        limit,
        offset,
        order: [[sortBy, sortOrder]],
        attributes: { exclude: ['password'] }
      });

      const users = rows.map(user => this.formatUserResponse(user));

      return {
        users,
        pagination: {
          page,
          limit,
          total: count,
          totalPages: Math.ceil(count / limit)
        }
      };
    } catch (error) {
      logger.error('获取用户列表失败:', error);
      throw error;
    }
  }

  /**
   * 根据ID获取用户
   */
  async getUserById(id: number): Promise<UserResponse> {
    try {
      const user = await User.findByPk(id, {
        attributes: { exclude: ['password'] },
        include: [
          {
            model: UserAddress,
            as: 'addresses',
            required: false
          }
        ]
      });

      if (!user) {
        throw new AppError('用户不存在', 404);
      }

      return this.formatUserResponse(user);
    } catch (error) {
      logger.error(`获取用户失败 (ID: ${id}):`, error);
      throw error;
    }
  }

  /**
   * 更新用户
   */
  async updateUser(id: number, userData: UpdateUserRequest): Promise<UserResponse> {
    try {
      const user = await User.findByPk(id);
      if (!user) {
        throw new AppError('用户不存在', 404);
      }

      // 检查用户名和邮箱是否已被其他用户使用
      if (userData.username || userData.email || userData.phone) {
        const conditions = [];
        if (userData.username) conditions.push({ username: userData.username });
        if (userData.email) conditions.push({ email: userData.email });
        if (userData.phone) conditions.push({ phone: userData.phone });

        const existingUser = await User.findOne({
          where: {
            id: { [Op.ne]: id },
            [Op.or]: conditions
          }
        });

        if (existingUser) {
          if (existingUser.username === userData.username) {
            throw new AppError('用户名已存在', 400);
          }
          if (existingUser.email === userData.email) {
            throw new AppError('邮箱已存在', 400);
          }
          if (existingUser.phone === userData.phone) {
            throw new AppError('手机号已存在', 400);
          }
        }
      }

      // 处理更新数据的类型转换
      const updateData: any = { ...userData };
      if (updateData.birthday) {
        updateData.birthday = new Date(updateData.birthday);
      }
      
      await user.update(updateData);
      logger.info(`用户更新成功: ${user.username} (ID: ${user.id})`);
      
      return this.formatUserResponse(user);
    } catch (error) {
      logger.error(`更新用户失败 (ID: ${id}):`, error);
      throw error;
    }
  }

  /**
   * 删除用户
   */
  async deleteUser(id: number): Promise<void> {
    try {
      const user = await User.findByPk(id);
      if (!user) {
        throw new AppError('用户不存在', 404);
      }

      // 删除用户相关的地址
      await UserAddress.destroy({ where: { userId: id } });
      
      // 删除用户
      await user.destroy();
      
      logger.info(`用户删除成功: ${user.username} (ID: ${user.id})`);
    } catch (error) {
      logger.error(`删除用户失败 (ID: ${id}):`, error);
      throw error;
    }
  }

  /**
   * 批量删除用户
   */
  async batchDeleteUsers(ids: number[]): Promise<void> {
    try {
      // 删除用户相关的地址
      await UserAddress.destroy({ where: { userId: { [Op.in]: ids } } });
      
      // 删除用户
      const deletedCount = await User.destroy({ where: { id: { [Op.in]: ids } } });
      
      logger.info(`批量删除用户成功，删除数量: ${deletedCount}`);
    } catch (error) {
      logger.error('批量删除用户失败:', error);
      throw error;
    }
  }

  /**
   * 更新用户状态
   */
  async updateUserStatus(id: number, status: 0 | 1): Promise<UserResponse> {
    try {
      const user = await User.findByPk(id);
      if (!user) {
        throw new AppError('用户不存在', 404);
      }

      await user.update({ status });
      logger.info(`用户状态更新成功: ${user.username} (ID: ${user.id}) -> ${status === 1 ? '正常' : '禁用'}`);
      
      return this.formatUserResponse(user);
    } catch (error) {
      logger.error(`更新用户状态失败 (ID: ${id}):`, error);
      throw error;
    }
  }

  /**
   * 获取用户统计信息
   */
  async getUserStats(): Promise<UserStatsResponse> {
    try {
      const now = new Date();
      const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
      const thisWeek = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);
      const thisMonth = new Date(now.getFullYear(), now.getMonth(), 1);

      const [
        totalUsers,
        activeUsers,
        inactiveUsers,
        newUsersToday,
        newUsersThisWeek,
        newUsersThisMonth,
        genderStats,
        levelStats
      ] = await Promise.all([
        User.count(),
        User.count({ where: { status: 1 } }),
        User.count({ where: { status: 0 } }),
        User.count({ where: { createdAt: { [Op.gte]: today } } }),
        User.count({ where: { createdAt: { [Op.gte]: thisWeek } } }),
        User.count({ where: { createdAt: { [Op.gte]: thisMonth } } }),
        User.findAll({
          attributes: ['gender', [User.sequelize!.fn('COUNT', '*'), 'count']],
          group: ['gender'],
          raw: true
        }),
        User.findAll({
          attributes: ['levelId', [User.sequelize!.fn('COUNT', '*'), 'count']],
          group: ['levelId'],
          raw: true
        })
      ]);

      // 处理性别分布
      const genderDistribution = { unknown: 0, male: 0, female: 0 };
      (genderStats as any[]).forEach((stat: any) => {
        switch (stat.gender) {
          case 0: genderDistribution.unknown = parseInt(stat.count); break;
          case 1: genderDistribution.male = parseInt(stat.count); break;
          case 2: genderDistribution.female = parseInt(stat.count); break;
        }
      });

      // 处理等级分布
      const levelDistribution: { [key: string]: number } = {};
      (levelStats as any[]).forEach((stat: any) => {
        levelDistribution[`level_${stat.levelId}`] = parseInt(stat.count);
      });

      return {
        totalUsers,
        activeUsers,
        inactiveUsers,
        newUsersToday,
        newUsersThisWeek,
        newUsersThisMonth,
        genderDistribution,
        levelDistribution
      };
    } catch (error) {
      logger.error('获取用户统计信息失败:', error);
      throw error;
    }
  }

  /**
   * 格式化用户响应数据
   */
  private formatUserResponse(user: User): UserResponse {
    return {
      id: user.id,
      username: user.username,
      email: user.email,
      phone: user.phone,
      avatar: user.avatar,
      nickname: user.nickname,
      gender: user.gender || 0,
      genderText: user.getGenderText(),
      birthday: user.birthday ? (user.birthday instanceof Date ? user.birthday.toISOString().split('T')[0] : String(user.birthday)) : undefined,
      status: user.status,
      statusText: user.getStatusText(),
      levelId: user.levelId,
      points: user.points,
      balance: parseFloat(user.balance.toString()),
      lastLoginAt: user.lastLoginAt?.toISOString(),
      createdAt: user.createdAt.toISOString(),
      updatedAt: user.updatedAt.toISOString()
    };
  }

  // 用户地址相关方法
  /**
   * 获取用户地址列表
   */
  async getUserAddresses(userId: number): Promise<UserAddressResponse[]> {
    try {
      const addresses = await UserAddress.findAll({
        where: { userId },
        order: [['isDefault', 'DESC'], ['createdAt', 'DESC']]
      });

      return addresses.map(address => this.formatAddressResponse(address));
    } catch (error) {
      logger.error(`获取用户地址列表失败 (用户ID: ${userId}):`, error);
      throw error;
    }
  }

  /**
   * 获取所有用户地址列表（管理员）
   */
  async getAllAddresses(params: AddressQueryParams): Promise<AddressListResponse> {
    try {
      const { page = 1, pageSize = 10, userId, receiverName, receiverPhone, province, city, isDefault } = params;
      const offset = (page - 1) * pageSize;

      // 构建查询条件
      const whereConditions: any = {};
      
      if (userId) {
        whereConditions.userId = parseInt(userId);
      }
      
      if (receiverName) {
        whereConditions.receiverName = {
          [Op.like]: `%${receiverName}%`
        };
      }
      
      if (receiverPhone) {
        whereConditions.receiverPhone = {
          [Op.like]: `%${receiverPhone}%`
        };
      }
      
      if (province) {
        whereConditions.province = {
          [Op.like]: `%${province}%`
        };
      }
      
      if (city) {
        whereConditions.city = {
          [Op.like]: `%${city}%`
        };
      }
      
      if (isDefault !== undefined && isDefault !== '') {
        whereConditions.isDefault = parseInt(isDefault);
      }

      // 查询地址列表和总数
      const queryOptions: any = {
        where: whereConditions,
        include: [
          {
            model: User,
            attributes: ['id', 'username', 'nickname'],
            as: 'user'
          }
        ],
        order: [['createdAt', 'DESC']],
        limit: pageSize,
        offset
      };
      
      const { rows: addresses, count: total } = await UserAddress.findAndCountAll(queryOptions);

      logger.info(`获取所有用户地址列表成功 (总数: ${total})`);
      
      const result = {
        list: addresses.map(address => this.formatAddressResponse(address)),
        total,
        page,
        pageSize
      };
      
      return result;
    } catch (error) {
      logger.error('获取所有用户地址列表失败:', error);
      throw error;
    }
  }

  /**
   * 创建用户地址
   */
  async createUserAddress(userId: number, addressData: CreateUserAddressRequest): Promise<UserAddressResponse> {
    try {
      const address = await UserAddress.create({
        ...addressData,
        userId
      });

      logger.info(`用户地址创建成功 (用户ID: ${userId}, 地址ID: ${address.id})`);
      return this.formatAddressResponse(address);
    } catch (error) {
      logger.error(`创建用户地址失败 (用户ID: ${userId}):`, error);
      throw error;
    }
  }

  /**
   * 更新用户地址
   */
  async updateUserAddress(userId: number, addressId: number, addressData: UpdateUserAddressRequest): Promise<UserAddressResponse> {
    try {
      const address = await UserAddress.findOne({
        where: { id: addressId, userId }
      });

      if (!address) {
        throw new AppError('地址不存在', 404);
      }

      await address.update(addressData);
      logger.info(`用户地址更新成功 (用户ID: ${userId}, 地址ID: ${addressId})`);
      
      return this.formatAddressResponse(address);
    } catch (error) {
      logger.error(`更新用户地址失败 (用户ID: ${userId}, 地址ID: ${addressId}):`, error);
      throw error;
    }
  }

  /**
   * 删除用户地址
   */
  async deleteUserAddress(userId: number, addressId: number): Promise<void> {
    try {
      const address = await UserAddress.findOne({
        where: { id: addressId, userId }
      });

      if (!address) {
        throw new AppError('地址不存在', 404);
      }

      await address.destroy();
      logger.info(`用户地址删除成功 (用户ID: ${userId}, 地址ID: ${addressId})`);
    } catch (error) {
      logger.error(`删除用户地址失败 (用户ID: ${userId}, 地址ID: ${addressId}):`, error);
      throw error;
    }
  }

  /**
   * 设置默认地址
   */
  async setDefaultAddress(userId: number, addressId: number): Promise<UserAddressResponse> {
    try {
      const address = await UserAddress.findOne({
        where: { id: addressId, userId }
      });

      if (!address) {
        throw new AppError('地址不存在', 404);
      }

      await address.update({ isDefault: 1 });
      logger.info(`设置默认地址成功 (用户ID: ${userId}, 地址ID: ${addressId})`);
      
      return this.formatAddressResponse(address);
    } catch (error) {
      logger.error(`设置默认地址失败 (用户ID: ${userId}, 地址ID: ${addressId}):`, error);
      throw error;
    }
  }

  /**
   * 格式化地址响应数据
   */
  private formatAddressResponse(address: UserAddress): UserAddressResponse {
    return {
      id: address.id,
      userId: address.userId,
      receiverName: address.receiverName,
      receiverPhone: address.receiverPhone,
      province: address.province,
      city: address.city,
      district: address.district,
      address: address.address,
      fullAddress: address.getFullAddress(),
      postalCode: address.postalCode,
      isDefault: address.isDefault,
      isDefaultText: address.getIsDefaultText(),
      createdAt: address.createdAt.toISOString(),
      updatedAt: address.updatedAt.toISOString()
    };
  }
}